import { onMounted,ref, reactive } from "vue";
const useCanvas = () => {
    // 数据
    const canvas = ref<HTMLCanvasElement | null>(null);
    const ctx = ref<CanvasRenderingContext2D | null>(null);
    const imageDataArr = ref<string[]>([]);
    const step = ref(-1);
    const state = reactive({
      type: 'huabi',
      isDraw: false,
      beginX: 0,
      beginY: 0,
      color: '#000',
      imageData: null as CanvasImageData | null,
    });
  const initCanvas = () => {
    canvas.value = document.getElementById('Canvas') as HTMLCanvasElement;
    if(!canvas.value) {
        throw new Error('Canvas element not found')
    }
    ctx.value = canvas.value.getContext("2d") as CanvasRenderingContext2D;
  }
  const changeType = (type: string) => {
    state.type = type;
  };
  
  const canvasDown = (e: MouseEvent) => {
    if (!canvas.value) return;
    state.isDraw = true;
    state.beginX = e.pageX - canvas.value.offsetLeft;
    state.beginY = e.pageY - canvas.value.offsetTop;
  };
  
  const canvasMove = (e: MouseEvent) => {
    if (!canvas.value) return;
    if (!ctx.value) return;
    if (!state.isDraw) return;
    const x = e.pageX - canvas.value.offsetLeft;
    const y = e.pageY - canvas.value.offsetTop;
    switch (state.type) {
      case "huabi":
        huabiFn(ctx.value, x, y);
        break;
      case "rect":
        rectFn(ctx.value, x, y);
        break;
      case "arc":
        arcFn(ctx.value, x, y);
        break;
    }
  };
  
  const canvasUp = () => {
    if (!canvas.value) return;
    if (!ctx.value) return;
    step.value++;
    if (step.value < imageDataArr.value.length) {
      imageDataArr.value.length = step.value;
    }
    imageDataArr.value.push(canvas.value.toDataURL());
    state.imageData = ctx.value.getImageData(0, 0, 800, 400);
    state.isDraw = false;
  };
  
  const huabiFn = (ctx: CanvasRenderingContext2D, x: number, y: number) => {
    ctx.beginPath();
    ctx.arc(x, y, 5, 0, 2 * Math.PI);
    ctx.fillStyle = state.color;
    ctx.fill();
    ctx.closePath();
  };
  
  const rectFn = (ctx: CanvasRenderingContext2D, x: number, y: number) => {
    const beginX = state.beginX;
    const beginY = state.beginY;
    ctx.clearRect(0, 0, 800, 400);
    state.imageData && ctx.putImageData(state.imageData, 0, 0, 0, 0, 800, 400);
    ctx.beginPath();
    ctx.strokeStyle = state.color;
    ctx.rect(beginX, beginY, x - beginX, y - beginY);
    ctx.stroke();
    ctx.closePath();
  };
  
  const arcFn = (ctx: CanvasRenderingContext2D, x: number, y: number) => {
    const beginX = state.beginX;
    const beginY = state.beginY;
    ctx.clearRect(0, 0, 800, 400);
    state.imageData && ctx.putImageData(state.imageData, 0, 0, 0, 0, 800, 400);
    ctx.beginPath();
    ctx.strokeStyle = state.color;
    ctx.arc(beginX, beginY, Math.round(Math.sqrt((x - beginX) * (x - beginX) + (y - beginY) * (y - beginY))), 0, 2 * Math.PI);
    ctx.stroke();
    ctx.closePath();
  };
  
  const saveImg = () => {
    if (!canvas.value) return;
    const url = canvas.value.toDataURL();
    const a = document.createElement("a");
    a.download = "sunshine";
    a.href = url;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  };
  
  const clear = () => {
    if (!ctx.value) return;
    state.imageData = null;
    ctx.value.clearRect(0, 0, 800, 400);
  };
  
  const revert = () => {
    if (!ctx.value) return;
    if (step.value >= 0) {
      step.value--;
      ctx.value.clearRect(0, 0, 800, 400);
      const canvasPic = new Image();
      canvasPic.src = imageDataArr.value[step.value];
      canvasPic.addEventListener("load", () => {
        if (!ctx.value) return;
        ctx.value.drawImage(canvasPic, 0, 0);
      });
    }
  };
  
  const recovery = () => {
    if (!ctx.value) return;
    if (step.value < imageDataArr.value.length - 1) {
      step.value++;
      ctx.value.clearRect(0, 0, 800, 400);
      const canvasPic = new Image();
      canvasPic.src = imageDataArr.value[step.value];
      canvasPic.addEventListener("load", () => {
        if (!ctx.value) return;
        ctx.value.drawImage(canvasPic, 0, 0);
      });
    }
  };
  onMounted(() => initCanvas())
    return {
        state,
        changeType,
        recovery,
        revert,
        saveImg,
        clear,
        canvasDown,
        canvasMove,
        canvasUp,
        arcFn,
        rectFn,
        huabiFn,
    }
}

export default useCanvas